package cn.iocoder.yudao.module.bpm.service.tohandle;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.convert.ConvertBeanUtil;
import cn.iocoder.yudao.framework.common.util.convert.Converter;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.bpm.api.tohandle.dto.*;
import cn.iocoder.yudao.module.bpm.controller.admin.tohandle.center.vo.BpmHandleTaskRespVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.tohandle.BpmHandleCollectDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.tohandle.BpmHandleFlowDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.tohandle.BpmHandleTaskDO;
import cn.iocoder.yudao.module.bpm.dal.mysql.tohandle.BpmHandleCollectMapper;
import cn.iocoder.yudao.module.bpm.dal.mysql.tohandle.BpmHandleFlowMapper;
import cn.iocoder.yudao.module.bpm.dal.mysql.tohandle.BpmHandleTaskMapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 待办中心接口
 *
 * @author huangjunwei
 */
@Service
@Slf4j
@Validated
public class BpmHandleCenterServiceImpl implements BpmHandleCenterService {
    @Resource
    BpmHandleTaskMapper bpmHandleTaskMapper;

    @Resource
    BpmHandleFlowMapper bpmHandleFlowMapper;

    @Resource
    BpmHandleCollectMapper bpmHandleCollectMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<Long> addToHandleFlowTask(List<BpmHandleFlowTaskCreateReqDTO> bpmHandleTaskRespDTOList) {
        List<Long> handleTaskIds = new ArrayList<>();
        for (BpmHandleFlowTaskCreateReqDTO taskCreateReqDTO : bpmHandleTaskRespDTOList) {
            BpmHandleFlowDO bpmHandleFlowDO = this.buildBpmHandleFlowDO(taskCreateReqDTO);
            if (bpmHandleFlowDO == null) {
                bpmHandleFlowDO = ConvertBeanUtil.convertToBean(taskCreateReqDTO, BpmHandleFlowDO.class);
                bpmHandleFlowMapper.insert(bpmHandleFlowDO);
            }
            if (CollectionUtils.isEmpty(taskCreateReqDTO.getBpmHandleTaskReqDTOs())) {
                continue;
            }
            List<BpmHandleTaskDO> bpmHandleTaskDOs = this.buildBpmHandleTaskDO(bpmHandleFlowDO.getId(), taskCreateReqDTO.getBpmHandleTaskReqDTOs());
            bpmHandleTaskMapper.insertBatch(bpmHandleTaskDOs);
            handleTaskIds = bpmHandleTaskDOs.stream().map(BpmHandleTaskDO::getId).collect(Collectors.toList());
        }
        return handleTaskIds;
    }

    private BpmHandleFlowDO buildBpmHandleFlowDO(BpmHandleFlowTaskCreateReqDTO taskCreateReqDTO) {
        Wrapper queryWrapper = new LambdaQueryWrapperX<BpmHandleFlowDO>()
                .eqIfPresent(BpmHandleFlowDO::getExtFlowId, taskCreateReqDTO.getExtFlowId())
                .eqIfPresent(BpmHandleFlowDO::getDeleted, 1);
        BpmHandleFlowDO bpmHandleFlowDO = bpmHandleFlowMapper.selectOne(queryWrapper);
        return bpmHandleFlowDO;
    }

    private List<BpmHandleTaskDO> buildBpmHandleTaskDO(Long flowId, List<BpmHandleTaskReqDTO> bpmHandleTaskReqDTOList) {
        return ConvertBeanUtil.convertToList(bpmHandleTaskReqDTOList, BpmHandleTaskDO.class,
                (Converter<BpmHandleTaskReqDTO, BpmHandleTaskDO>) (from, to) -> {
                    to.setBpmHandleFlowId(flowId);
                    to.setTaskStatus(from.getTaskStatus());
                });
    }


    /**
     * 查询待办任务列表
     *
     * @param reqDTO
     * @return 待办列表
     */
    @Override
    public PageResult<BpmHandleTaskRespVO> getToHandleTaskList(PageParam pageParam, BpmHandleTaskSearchReqDTO reqDTO) {
        Wrapper queryWrapper = new LambdaQueryWrapperX<BpmHandleFlowDO>()
                .eqIfPresent(BpmHandleFlowDO::getExtFlowId, reqDTO.getFlowId())
                .eqIfPresent(BpmHandleFlowDO::getSourceSystemId, reqDTO.getSourceSystemId())
                .eqIfPresent(BpmHandleFlowDO::getSenderUsername, reqDTO.getSenderUsername())
                .eqIfPresent(BpmHandleFlowDO::getSenderName, reqDTO.getSenderName())
                .eqIfPresent(BpmHandleFlowDO::getFlowStatus, reqDTO.getFlowStatus())
                .eqIfPresent(BpmHandleFlowDO::getDeleted, 1);
        Long countTotal = bpmHandleTaskMapper.selectCount(queryWrapper);
        PageResult<BpmHandleTaskDO> handleTaskDOPageResult = bpmHandleTaskMapper.selectPage(pageParam, queryWrapper);
        List<BpmHandleTaskRespVO> bpmHandleTaskRespVOs = ConvertBeanUtil.convertToList(handleTaskDOPageResult.getList(), BpmHandleTaskRespVO.class);
        return new PageResult<>(bpmHandleTaskRespVOs, countTotal);
    }

    /**
     * 添加收藏
     *
     * @param createCollectReqDtos
     */
    @Override
    public List<Long> addCollect(List<BpmCollectCreateReqDto> createCollectReqDtos) {
        List<BpmHandleCollectDO> bpmHandleCollectDOs = ConvertBeanUtil.convertToList(createCollectReqDtos, BpmHandleCollectDO.class);
        bpmHandleCollectMapper.insertBatch(bpmHandleCollectDOs);
        List<Long> collectIds = bpmHandleCollectDOs.stream().map(BpmHandleCollectDO::getId).distinct().collect(Collectors.toList());
        return collectIds;
    }

    /**
     * 分页查询我的收藏
     *
     * @param pageParam
     * @param bpmCollectSearchReqDto
     */
    @Override
    public PageResult<BpmCollectInfoResDto> searchCollect(PageParam pageParam, BpmCollectSearchReqDto bpmCollectSearchReqDto) {
        BpmHandleCollectDO bpmHandleCollectDO = ConvertBeanUtil.convertToBean(bpmCollectSearchReqDto, BpmHandleCollectDO.class);
        PageResult<BpmHandleCollectDO> bpmHandleCollectDOPageResult = bpmHandleCollectMapper.selectPage(pageParam, null);
        List<BpmCollectInfoResDto> bpmCollectInfoResDtos = ConvertBeanUtil.convertToList(bpmHandleCollectDOPageResult.getList(), BpmCollectInfoResDto.class);
        return new PageResult<BpmCollectInfoResDto>(bpmCollectInfoResDtos, Long.valueOf(bpmCollectInfoResDtos.size()));
    }


}
